/*
 * $Id: AppResource.java 17 2014-08-28 10:52:50Z ratking $
 *
 * Copyleft (C) 2014 RatKing. All wrongs reserved.
 */
package cn.ratking.demo.jaws6.resource;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.enterprise.event.Observes;
import javax.cache.Cache;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.slf4j.Logger;

import cn.ratking.demo.jaws6.cache.SysCodeCache;
import cn.ratking.demo.jaws6.cache.SysCodeNameCache;
import cn.ratking.demo.jaws6.cache.SysCodeValueCache;
import cn.ratking.demo.jaws6.model.SysCode;
import cn.ratking.demo.jaws6.system.service.SysCodeService;

/**
 * 应用程序资源
 */
@Named
@RequestScoped
public class AppResource implements Serializable {

    @Inject
    private transient Logger log;
    /** 系统代码服务 */
    @Inject
    private SysCodeService sysCodeService;
    /** 系统代码缓存 */
    @Inject
    @SysCodeCache
    private Cache<String, List<SysCode>> sysCodeCache;
    /** 系统代码名称缓存 */
    @Inject
    @SysCodeNameCache
    private Cache<String, String> sysCodeNameCache;
    /** 系统代码值缓存 */
    @Inject
    @SysCodeValueCache
    private Cache<String, String> sysCodeValueCache;

    /**
     * 按代码类型查询有效的系统代码(使用缓存，在页面中生成下拉菜单)
     *
     * @param codeType 代码类型
     * @return 系统代码列表
     */
    public List<SysCode> getSysCodeList(String codeType) {
        //log.debug("Debug: AppResource.getSysCodeList(), codeType=" + codeType);
        if (codeType == null || codeType.trim().length() == 0) {
            log.warn("警告：AppResource.getSysCodeList(), codeType=" + codeType);
            return null;
        }

        String cacheKey = codeType;
        List<SysCode> sysCodeList = sysCodeCache.get(cacheKey);
        if (sysCodeList == null) {
            // 按项目代码和代码类型查询系统代码列表，仅查有效的
            sysCodeList = sysCodeService.findByCodeType(codeType);
            sysCodeCache.put(cacheKey, sysCodeList);
        }
        return sysCodeList;
    }

    /**
     * 按代码类型和代码值查询代码名称(使用缓存，在列表中由代码反查中文名称).
     *
     * @param codeType 代码类型
     * @param codeValue 代码值
     * @return 代码名称
     */
    public String getCodeName(String codeType, String codeValue) {
        //log.debug("Debug: AppResource.getSysCodeList(), codeType=" + codeType + ", codeValue=" + codeValue);
        if (codeType == null || codeType.trim().length() == 0
                || codeValue == null || codeValue.trim().length() == 0) {
            return null;
        }

        String cacheKey = codeType + ":" + codeValue;
        String codeName = sysCodeNameCache.get(cacheKey);
        if (codeName == null) {
            // 按代码类型和代码值查询系统代码(用于缓存，在列表中由代码反查中文名称)
            SysCode sysCode = sysCodeService.findByCodeTypeAndCodeValue(codeType, codeValue);
            if (sysCode != null) {
                codeName = sysCode.getCodeName();
                sysCodeNameCache.put(cacheKey, codeName);
            } else {
                log.warn("找不到系统代码[codeType=" + codeType + ", codeValue=" + codeValue + "]");
            }
        }
        return codeName;
    }

    /**
     * 按代码类型和代码名称查询代码值(使用缓存，由中文名称查代码值).
     *
     * @param codeType 代码类型
     * @param codeName 代码名称
     * @return 代码值
     */
    public String getCodeValue(String codeType, String codeName) {
        //log.debug("Debug: AppResource.getCodeValue(), codeType=" + codeType + ", codeName=" + codeName);
        if (codeType == null || codeType.trim().length() == 0
                || codeName == null || codeName.trim().length() == 0) {
            return null;
        }

        String cacheKey = codeType + ":" + codeName;
        String codeValue = sysCodeValueCache.get(cacheKey);
        if (codeValue == null) {
            // 按代码类型和代码名称查询系统代码(用于缓存，在系统代码中由名称查代码)
            SysCode sysCode = sysCodeService.findByCodeTypeAndCodeName(codeType, codeName);
            if (sysCode != null) {
                codeValue = sysCode.getCodeValue();
                sysCodeValueCache.put(cacheKey, codeValue);
            } else {
                log.warn("找不到系统代码[codeType=" + codeType + ", codeName=" + codeName + "]");
            }
        }

        return codeValue;
    }

    /**
     * 事件观察者.
     * 当观察到系统代码变化事件时，清空缓存中的代码
     *
     * @param sysCode 发生变化的系统代码
     */
    public void observeSysCode(@Observes SysCode sysCode) {
        //log.debug("Debug: AppResource.observeSysCode(), sysCode=" + sysCode);
        sysCodeCache.clear();
        sysCodeNameCache.clear();
        sysCodeValueCache.clear();
    }

    /**
     * 返回下载文件的文件名，避免中文乱码
     *
     * @param fileName 原文件名
     * @return 下载文件时使用的文件名(不加时间戳)
     */
    public String getFileName(String fileName) {
        return this.getFileName(fileName, false);
    }

    /**
     * 返回下载文件的文件名，避免中文乱码
     *
     * @param fileName 原文件名(不含扩展名)
     * @param timeStampFlag 是否加时间戳
     * @return 下载文件时使用的文件名(不含扩展名)
     */
    public String getFileName(String fileName, boolean timeStampFlag) {
        String newFileName = null;
        try {
            newFileName = new String(fileName.getBytes("GBK"), "iso-8859-1");
        } catch (UnsupportedEncodingException uee) {
            log.error("内部错误：不支持的编码：" + uee.getMessage(), uee);
            newFileName = fileName + "[ERROR]";
        }
        if (timeStampFlag) {
            newFileName += "-" + new SimpleDateFormat("yyyyMMdd").format(new Date());
        }
        return newFileName;
    }
}
